package org.KeyCrafter.obj.type;

import org.KeyCrafter.ds.dict.Dict;
import org.KeyCrafter.ds.dict.DictType;
import org.KeyCrafter.ds.dict.HashDict;
import org.KeyCrafter.ds.dict.MurmurHash2;
import org.KeyCrafter.ds.skiplist.SkipList;
import org.KeyCrafter.ds.skiplist.ZSkipList;

import java.util.Iterator;

public class DefaultZSetType implements ZSetType{
    private static final DictType type = new MurmurHash2();
    // 字典，键为成员，值为分值
    // 用于支持 O(1) 复杂度的按成员取分值操作
    private Dict dict = new HashDict(type,null);
    // 跳跃表，按分值排序成员
    // 用于支持平均复杂度为 O(log N) 的按分值定位成员操作
    // 以及范围操作
    private SkipList zsl = new ZSkipList();
    @Override
    public byte encoding() {
        return KeyCrafter_ENCODING_SKIPLIST;
    }

    @Override
    public Object content() {
        return null;
    }

    @Override
    public int add(double score, Object obj) {
        return (int)add(score, obj, false);
    }

    @Override
    public double incr(Object obj, double increment) {
        return add(increment, obj, true);
    }

    @Override
    public int length() {
        return (int) zsl.length();
    }

    @Override
    public Node[] getNodesByRange(int start, int rangeLen, boolean revers) {
        Iterator<SkipList.Node> iterator;
        if (revers) {
            iterator = zsl.getIteratorByRank(zsl.length() - start,true);
        } else {
            iterator = zsl.getIteratorByRank(start+1,false);
        }
        Node[] nodes = new Node[rangeLen];
        for (int i = 0; i < rangeLen; i++) {
            SkipList.Node next = iterator.next();
            nodes[i] = new Node() {
                @Override
                public double score() {
                    return next.getScore();
                }
                @Override
                public Object member() {
                    return next.getObject();
                }
            };
        }
        return nodes;
    }

    @Override
    public Iterator<Node> iterator() {
        Iterator<SkipList.Node> iterator = zsl.iterator(false);
        return new Iterator<Node>() {
            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public Node next() {
                SkipList.Node next = iterator.next();
                if (next != null) {
                    return new Node() {
                        @Override
                        public double score() {
                            return next.getScore();
                        }
                        @Override
                        public Object member() {
                            return next.getObject();
                        }
                    };
                } else {
                    return null;
                }
            }
        };
    }


    private double add(double score, Object obj, boolean incr) {
        // 查看成员是否存在
        Dict.Entry de = dict.find(obj);
        if (de != null) {
            // 成员存在
            // 取出成员
            Object curObj = de.getKey();
            // 取出分值
            double curScore = (double) de.getValue();

            // 增加分数时执行
            if (incr) {
                score += curScore;
            }

            if (score != curScore) {
                // 删除原有元素
                zsl.delete(curScore,curObj);
                // 重新插入元素
                zsl.insert(score,obj);
                // 更新字典的分值
                de.setValue(score);
            }
            return incr ? score : 0 ;
        } else {
            // 元素不存在，直接添加到跳跃表
            SkipList.Node node = zsl.insert(score, obj);
            // 将元素关联到字典
            dict.add(node.getObject(),node.getScore());
            return incr ? score : 1;
        }
    }


    @Override
    public Double getScore(Object obj) {
        Dict.Entry de = dict.find(obj);
        if (de != null) {
            return (Double) de.getValue();
        }
        return null;
    }
}
